/**
 * Title: JsonHttpResponseHandler.java
 * Description:
 * Copyright: Copyright (c) 2008
 * Company:深圳彩讯科技有限公司
 * Author 罗旭东 (hi@luoxudong.com)
 * Date 2013-8-9 下午5:17:08
 * Version 1.0 
 */
package com.luoxudong.phonenumber.service.net.http.asynchttp;

import android.os.Message;

import com.google.gson.Gson;
import com.luoxudong.phonenumber.logic.common.BaseConfig;
import com.luoxudong.phonenumber.service.exception.PhoneNumberException;
import com.luoxudong.phonenumber.service.exception.PhoneNumberExceptionCode;
import com.luoxudong.phonenumber.service.net.http.asynchttp.interfaces.ISimpleJsonRequestListener;
import com.luoxudong.phonenumber.service.net.http.asynchttp.model.BaseResponse;
import com.luoxudong.phonenumber.service.net.http.asynchttp.model.ServerResult;
import com.luoxudong.phonenumber.service.net.http.httpclient.Header;
import com.luoxudong.phonenumber.service.net.http.httpclient.HttpStatus;
import com.luoxudong.phonenumber.service.utils.FileUtil;

/** 
 * ClassName: JsonHttpResponseHandler 
 * Description:json请求结果回调
 * Create by 罗旭东
 * Date 2013-8-9 下午5:17:08 
 */
public class JsonHttpResponseHandler<M extends BaseResponse<M>> extends AsyncHttpResponseHandler{
	protected static final int SUCCESS_JSON_MESSAGE = 100;
	
	private Class<M> responseClass = null;
	
	private ISimpleJsonRequestListener<M> listener = null;

	public JsonHttpResponseHandler(Class<M> responseClass, ISimpleJsonRequestListener<M> listener)
	{
		this.listener = listener;
		this.responseClass = responseClass;
		//this.listener = listener;
	}

    /**
     * Fired when a request returns successfully and contains a json object
     * at the base of the response string. Override to handle in your
     * own code.
     * @param statusCode the status code of the response
     * @param headers the headers of the HTTP response
     * @param response the parsed json object found in the server response (if any)
     */
    public void onSuccess(int statusCode, Header[] headers, M response) {
        onSuccess(statusCode, response);
    }

    /**
     * Fired when a request returns successfully and contains a json object
     * at the base of the response string. Override to handle in your
     * own code.
     * @param statusCode the status code of the response
     * @param response the parsed json object found in the server response (if any)
     */
    public void onSuccess(int statusCode, M response) {
        onSuccess(response);
    }

    /**
     * Fired when a request returns successfully and contains a json object
     * at the base of the response string. Override to handle in your
     * own code.
     * @param response the parsed json object found in the server response (if any)
     */
    public void onSuccess(M response) {
    	ServerResult serverResult = response.getServerResult();
    	
    	if (serverResult == null)
    	{
    		onFailure(PhoneNumberExceptionCode.invalidJsonParams.getErrorCode(), new PhoneNumberException("缺少参数[" + PhoneNumberExceptionCode.invalidJsonParams.getErrorCode() + "]"));
    	}
    	else if (serverResult.getResultCode() == PhoneNumberExceptionCode.success.getErrorCode())//返回成功
    	{
    		if (listener != null)
        	{
    			listener.onSuccess(response);
        	}
    	}
    	else
    	{
    		onFailure(PhoneNumberExceptionCode.jsonResultError.getErrorCode(), new PhoneNumberException(serverResult));
    	}
    	
    }
    
    /*@Override
    public void onFailure(int errorCode, Throwable e) {
    	String errorMsg = DataCheckUtil.errorCodeCheck(errorCode);
    	
    	onFailure(errorCode, errorMsg, e);
    }*/
    
    @Override
    public void onFailure(int errorCode, String errorMsg, Throwable e) {
    	if (listener != null)
    	{
    		listener.onFailed(errorCode, errorMsg);
    	}
    }

    @Override
    protected void sendSuccessMessage(int statusCode, Header[] headers, String responseBody) {
        if (statusCode != HttpStatus.SC_NO_CONTENT){
            try {
                M jsonResponse = parseResponse(responseBody);
                sendMessage(obtainMessage(SUCCESS_JSON_MESSAGE, new Object[]{statusCode, headers, jsonResponse}));
    	    } catch(PhoneNumberException e) {
    	        sendFailureMessage(e.getExceptionCode(), e);
    	    }
        } else {
            sendMessage(obtainMessage(SUCCESS_JSON_MESSAGE, new Object[]{statusCode, headers, null}));
    	}
    }
    
    //
    // Pre-processing of messages (in original calling thread, typically the UI thread)
    //

    @Override
    protected void handleMessage(Message msg) {
        switch(msg.what){
            case SUCCESS_JSON_MESSAGE:
                Object[] response = (Object[]) msg.obj;
                
                handleSuccessJsonMessage(((Integer) response[0]).intValue(),(Header[]) response[1] , (M)response[2]);
                break;
            default:
                super.handleMessage(msg);
        }
    }

    protected void handleSuccessJsonMessage(int statusCode,Header[] headers, M jsonResponse) {
        if(jsonResponse != null) {
            onSuccess(statusCode, headers, jsonResponse);
        } else {
            onFailure(PhoneNumberExceptionCode.unknownHostException.getErrorCode(), new PhoneNumberException("非json字符串 "));
        }
    }

    protected M parseResponse(String responseBody) {
        M result = null;
        //trim the string to prevent start with blank, and test if the string is valid JSON, because the parser don't do this :(. If Json is not valid this will return null
		responseBody = responseBody.trim();
		Gson gson = new Gson();
		if(responseBody.startsWith("{") || responseBody.startsWith("[")) {//合法的json字符串
			try {
				result = gson.fromJson(responseBody, responseClass);
			} catch (Exception e) {
				throw new PhoneNumberException(PhoneNumberExceptionCode.jsonParseException.getErrorCode(), e);
			}
			
		}
		
		if (result == null) {
			result = null;
		}
		return result;
    }

    @Override
    protected void handleFailureMessage(int errorCode, Throwable e) {
    	onFailure(errorCode, e);
    }
}
